import os
import re
import xlrd
from configparser import ConfigParser
from openpyxl import load_workbook


class Excel2XmlTask:
    array_item_regex_array = {
        r"num_product_[0-9]+": ["num_product", "plurals", "quantity"],
        r"delete_or_cancel_[0-9]+": ["delete_or_cancel", "string-array", None],
        r"main_tab_titles_[0-9]+": ["main_tab_titles", "string-array", None],
    }
    special_item_label_array = ["one", "other"]

    def __init__(
            self,
            excelFileAbsPath,
            sheetName,
            xmlFileAbsPath,
            xmlFileType,
            last_line,
            new_key_should_skip,
            keyColumnIndex=0,
            valueColumnIndex=2,
            enValueColumnIndex=1,
    ):
        """
        :param xmlFileType: xls 或 xlsx 后缀
        """
        self.excelFileAbsPath = excelFileAbsPath
        self.sheetName = sheetName
        self.xmlFileAbsPath = xmlFileAbsPath
        self.xmlFileType = xmlFileType
        self.last_line = last_line
        self.new_key_should_skip = new_key_should_skip
        self.keyColumnIndex = keyColumnIndex
        self.valueColumnIndex = valueColumnIndex
        self.enValueColumnIndex = enValueColumnIndex

        cfg = ConfigParser()
        cfg.read('excel2xml.ini', encoding='utf-8')
        self.res_dir = cfg.get('production', 'androidProjectResAbsDir')
        sameXmlPath = xmlFileAbsPath[
                      xmlFileAbsPath.rindex(os.sep, 0, xmlFileAbsPath.rindex(os.sep)):
                      ]
        print(self.res_dir + sameXmlPath)
        originalEnStringFile = open(self.res_dir + sameXmlPath, "r", encoding='utf-8')
        self.originalEnStringFileContent = originalEnStringFile.read()
        originalEnStringFile.close()

    def takeKey(self, elem):
        return elem[0]

    def run(self):
        if "xlsx" == self.xmlFileType:
            self.__runXlsx()
        else:
            book = xlrd.open_workbook(self.excelFileAbsPath)
            sheet = book.sheet_by_name(self.sheetName)
            dir = self.xmlFileAbsPath[0: self.xmlFileAbsPath.rindex(os.sep)]
            if not os.path.exists(dir):
                os.makedirs(dir)
            file = open(self.xmlFileAbsPath, "w")
            file.write('<?xml version="1.0" encoding="utf-8"?>\n<resources>\n')

            pair_list = []
            # key 跟英文翻译都为空
            bothEmpty = []
            for rx in range(sheet.nrows):
                if rx <= 0:
                    continue
                row = sheet.row(rx)
                key = row[self.keyColumnIndex].value
                value = row[self.valueColumnIndex].value
                enValue = row[self.enValueColumnIndex].value
                if (enValue == None or "" == enValue) and (key == None or "" == key):
                    bothEmpty.append(value)
                    raise Exception("key 且英文为空", value)
                pair_list.append((key, value, enValue))

            pair_list.sort(key=self.takeKey)
            special_map = {}
            notFound = []
            notFoundByRegex1 = []
            notFoundByRegex2 = []
            for rx in range(len(pair_list)):
                key = pair_list[rx][0]
                value = pair_list[rx][1]
                enValue = pair_list[rx][2]
                """
                if key == None or "" == key:
                    if value == None or "" == value:
                        print(enValue, self.xmlFileAbsPath)
                        raise Exception("key value 均为空")
                    # key 为空，去老英文 strings.xml 中找 value 相同的条目的 key
                    regex_string = (
                        '<string\s+name\s*=\s*"([^"]+)"\s*>%s</\s*string\s*>' % (value)
                    )
                    try:
                        search_result = re.search(
                            r"" + regex_string, self.originalEnStringFileContent, re.I
                        )
                    except re.error:

                        if self.originalEnStringFileContent.find(enValue) != -1:
                            notFoundByRegex1.append((enValue, value))

                        else:
                            notFound.append((enValue, value))

                    else:
                        if search_result:
                            # print("*******************************************")
                            # print("找到前", ("key=%s, enValue=%s, value=%s, self.xmlFileAbsPath=%s")%(key, enValue, value, self.xmlFileAbsPath))
                            key = search_result.group(1)
                            # print("找到", key)

                            # print("*******************************************")
                        else:

                            if self.originalEnStringFileContent.find(enValue) != -1:
                                notFoundByRegex2.append((enValue, value))

                            else:
                                notFound.append((enValue, value))
                """
                foundItem = None
                for __key in self.array_item_regex_array.keys():
                    regex = __key
                    if re.match(regex, key, re.I):
                        foundItem = __key
                        break

                if foundItem:

                    if foundItem in special_map:
                        special_map[foundItem].append(value)
                    else:
                        special_map[foundItem] = []
                        special_map[foundItem].append(value)

                else:
                    file.write('<string name="{0}">{1}</string>\n'.format(key, value))

            if len(notFound) > 0:
                print("@@@@@@@@@@@@@@@@@@@@死活找不到@@@@@@@@@@@@@@@@@@@@")
                for i in notFound:
                    print("enValue=%s，value=%s" % (i[0], i[1]))
                print("@@@@@@@@@@@@@@@@@@@@死活找不到@@@@@@@@@@@@@@@@@@@@")

            if len(notFoundByRegex1) > 0:
                print("--------------------正则找不到，但不使用正则找到了--------------------")
                for i in notFoundByRegex1:
                    print("enValue=%s，value=%s" % (i[0], i[1]))
                print("--------------------正则找不到，但不使用正则找到了--------------------")

            if len(notFoundByRegex2) > 0:
                print("###########################################")
                for i in notFoundByRegex2:
                    print("正则找不到，但不使用正则找到了，enValue=%s，value=%s" % (i[0], i[1]))
                print("###########################################")

            if len(special_map) > 0:
                for key in special_map.keys():
                    special_key = self.array_item_regex_array[key][0]
                    special_label = self.array_item_regex_array[key][1]
                    special_item_label = self.array_item_regex_array[key][2]
                    file.write('<{0} name="{1}">\n'.format(special_label, special_key))
                    index = 0

                    for value in special_map[key]:

                        if special_item_label:
                            file.write(
                                '<item {0}="{1}">{2}</item>\n'.format(
                                    special_item_label,
                                    self.special_item_label_array[index],
                                    value,
                                )
                            )
                            index = index + 1
                        else:
                            file.write("<item>{0}</item>\n".format(value))
                    file.write("</{0}>\n".format(special_label))

            file.write("</resources>")
            file.close()

    def __runXlsx(self):
        book = load_workbook(filename=self.excelFileAbsPath, read_only=True)
        sheet = book.get_sheet_by_name(self.sheetName)
        first_r_sign_pos = self.xmlFileAbsPath.rindex(os.sep)
        dir = self.xmlFileAbsPath[0:first_r_sign_pos]
        second_r_sign_pos = dir.rindex(os.sep)  # 从右往左数的第二个斜杠的位置
        # newFileName 为 \values-xx\strings.xml
        newFileName = self.xmlFileAbsPath[second_r_sign_pos: len(self.xmlFileAbsPath)]
        newFileAbs = self.res_dir + newFileName
        print("newFileAbs: [%s]" % newFileAbs)
        oldFile = open(newFileAbs, encoding='utf-8')
        oldFileContent = oldFile.read()
        oldFile.close()
        oldKvMap = self.getKvMap(oldFileContent)
        print("dir: [%s]\nnewFileName: [%s]" % (dir, newFileName))
        print("self.keyColumnIndex: [%s]" % (self.keyColumnIndex))
        if not os.path.exists(dir):
            os.makedirs(dir)
        append = ""
        tobeDeleteRow = []
        print("总行数: {0}".format(self.last_line))
        for row in range(self.last_line):
            key = sheet.cell(row + 1, self.keyColumnIndex).value
            value = sheet.cell(row + 1, self.valueColumnIndex).value
            #print('{0}: {1}'.format( key, value) )
            if (key == None or key == ""
                    or value == None
                    or value == ""
                    or value == "待补充"
                    or key == 'android 没用该文案'
                    or key == '-'
                    or key == '?'
                    or key == 'key'

            ):
                continue

            search_result = re.search(r'<string[^"]+?"([^"]+)"', key, re.I)
            if search_result:
                key = search_result.group(1)
                #print(key)
            '''    
            if key not in [

                "shopping_cart_empty",
                "pending_payment",
                "awaiting_receipt",
                "why_buy_from_oraimo",
                "tap_to_reload",
                "salutatory_oration",
                "psl_input_email",
                "psw_format_tips",
                "rating_review",
                "pic_from_album",
                "go_setting",
                "storage_permission_tips",
                "camera_permission_refuse_tips",
                "album_permission_refuse_tips",
                "logout_tips",
                "invoice",
                "check_for_updates",
                "clear_cache_tips",
                "no_order",
                "check_logistics",
                "address_area",
                "pls_select_area",
                "pls_input_detail_address",
                "confirm_delete_selected_address_tip",
                "content",
                "picture",
                "add_on",
                "login_invalid_tips",
                "please_select_another_items",
                "could_you_tell_me_the_reason",
                "point_show_content_do_not_use",

            ]:
                continue
            '''
            if ( self.new_key_should_skip is not None
                        and (key in self.new_key_should_skip )
                    ):
                continue
            exists = self.sameKeyValue(key, value, oldKvMap)
            if exists:
                #print('存在 | {0}: {1}'.format( key, value) ) 
                continue
            sameKey = self.sameKey(key, oldKvMap)
            if sameKey[1] != None:
                if sameKey[1].replace('\\', '') == value:
                    continue
            if sameKey[0]:
                oldValue = sameKey[1]
                oldValueArr = oldValue.split("%s")
                allSubstringFound = True
                for substring in oldValueArr:
                    if substring not in value:
                        allSubstringFound = False
                        break
                if not allSubstringFound:
                    # key 相同，value 不同，把 key-oldValue 存起来待删除
                    tobeDeleteRow.append((key, sameKey[1]))
                    append = append + ('<string name="{0}">{1}</string>\n'.format(key, value))
                continue
            print(' {0}: {1}'.format( key, value) ) 
            append = append + ('<string name="{0}">{1}</string>\n'.format(key, value))
        # 删除旧文件中有更新的字段
        for pair in tobeDeleteRow:
            # <string[\s\S]*?name[ ]*=[ ]*"([^"]+)"[^>]*>([\s\S]+?)</
            regex = '<string[^>]*?name[ ]*=[ ]*"' + pair[0] + '"[^>]*>' + pair[1] + '</[ ]*?string[ ]*?>'
            print('删除查找正则: {0}'.format(regex))
            tobeDeleteFound = re.search(r'' + regex, oldFileContent)
            if tobeDeleteFound:
                start_index = tobeDeleteFound.span()[0]
                end_index = tobeDeleteFound.span()[1]
                print('删除{0} | start_index: {1} | end_index: {2}'.format(pair[0], start_index, end_index))
                oldFileContent = oldFileContent[0: start_index] + oldFileContent[end_index:]
        search_result = re.search(r"</\s*resources\s*>", oldFileContent)
        newFileContent = ""
        if search_result and append != None and "" != append:

            start_index = search_result.span()[0]
            end_index = search_result.span()[1]
            newFileContent = oldFileContent[0:start_index]

            newFileContent = newFileContent + append
            newFileContent = newFileContent + "</resources>"
            newFile = open(newFileAbs, "w", encoding='utf-8')
            newFile.write(newFileContent)
            newFile.close()
        else:
            print("没找到</resources> 或者 append[%s]" % append)

    def sameKey(self, newKey, oldKvMap: dict):
        for oldKv in oldKvMap.keys():
            if oldKv == newKey:
                return (True, oldKvMap.get(oldKv))
        return (False, None)

    """
    Excel 表里的 key value 跟 strings.xml 文件中的一样
    """

    def sameKeyValue(self, newKey, newValue, oldKvMap: dict):
        for oldKv in oldKvMap.keys():
            if oldKv == newKey and oldKvMap.get(oldKv) == newValue:
                return True
        return False

    def getKvMap(self, fileContent):
        regex = re.compile(r'<string[^"]+?"([^"]+?)"[^>]*?>([\s\S]+?)</')
        all_found = regex.findall(fileContent)

        result: dict = {}
        for item_found in all_found:
            result[item_found[0]] = item_found[1]
        return result
